package cn.smxy.ln.controller;

import cn.hutool.core.date.DateUtil;
import cn.smxy.ln.common.lang.Result;
import cn.smxy.ln.common.utils.RedisUtil;
import cn.smxy.ln.pojo.WorkRegister;
import cn.smxy.ln.service.WorkRegisterService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.cache.annotation.Cacheable;

import java.util.Date;
import java.util.List;

/**
 * @author ln
 * @date 2022年05月20日 20:18
 */
@RestController
@RequestMapping("/workregister")
public class WorkRegisterController {

    @Autowired
    WorkRegisterService workRegisterService;

    @Autowired
    RedisUtil redisUtil;

    /*然后在需要的方法上添加缓存注解，
    @Cacheable ----根据方法对其返回结果进行缓存，下次请求时，如果缓存存在，则直接读取缓存数据返回;如果缓存不存在，则执行方法，并把返回的结果存入缓存中。一般用在查询方法上。
    @CachePut ----使用该注解标志的方法，每次都会执行，并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据，而不需要再去查询数据库。一般用在新增方法上。
    @CacheEvict —使用该注解标志的方法，会清空指定的缓存。一般用在更新或者删除方法上。*/

    @HystrixCommand(fallbackMethod = "hystrixGetList")
    @GetMapping("/list")
    @Cacheable(cacheNames = "workRegister", unless = "#result.getData() == null")    //key:缓存数据时使用的 key，可以用它来指定。默认是使用方法参数的值；cacheNames/value：二者选其一即可，指定缓存组件的名字
    public Result queryAll(@RequestParam(value = "teacherId", required = false) Long teacherId, @RequestParam(value = "projectId", required = false) Long projectId, @RequestParam(value = "workId", required = false) Long workId, @RequestParam(value = "workContent", required = false) String workContent, @RequestParam(value = "startTime", required = false) Date startTime, @RequestParam(value = "endTime", required = false) Date endTime, @RequestParam(value = "createTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date createTime) {
        QueryWrapper query = new QueryWrapper();
        if (teacherId != null) {
            query.eq("teacher_id", teacherId);
        }
        if (projectId != null) {
            query.eq("project_id", projectId);
        }
        if (workId != null) {
            query.eq("work_id", workId);
        }
        if (workContent != null) {
            query.like("work_content", workContent);
        }
        if (startTime != null && endTime != null && createTime != null) {
            return Result.fail("startTime，endTime，createTime不能同时有值，会矛盾");
        }
        if ((startTime != null && endTime == null) || (startTime == null && endTime != null)) {
            return Result.fail("startTime，endTime应该同时为空或同时不为空");
        }
        if (startTime == null && endTime == null && createTime != null) {
            query.eq("create_time", createTime);
        }
        if (startTime != null && endTime != null && createTime == null) {
            query.ge("create_time", startTime);
            query.le("create_time", endTime);
        }
        List<WorkRegister> list = workRegisterService.list(query);
        if (list == null) {
            throw new RuntimeException("数据库没有workregister数据，或者信息无法找到");
        }
        return Result.succ(list);
    }
    
    /*
     * @author ln
     * @date 2022-05-20 20:37 
     * @return java.util.List<cn.smxy.ln.pojo.WorkRegister>
     * 熔断
     */
    public Result hystrixGetList(Long teacherId, Long projectId, Long workId, String workContent, Date startTime, Date endTime, Date createTime) {
        return Result.fail("没有得到对应的信息，数据库workregister是空的，或者刷新试试");
    }


    /**
     * DiscoveryClient 可以用来获取一些配置的信息，得到具体的微服务！
     */
    @Autowired
    private DiscoveryClient client;

    /*
     * @author ln
     * @date 2022-05-20 20:33 
     * @return java.lang.Object
     * 获取一些注册进来的微服务的信息
     */
    @GetMapping("/discovery")
    public Result discovery() {
        // 获取微服务列表的清单
        List<String> services = client.getServices();
        System.out.println("discovery=>services" + services);
        // 得到一个具体的微服务信息,通过具体的微服务id，applicaioinName；
        List<ServiceInstance> instances = client.getInstances("TPA-SPRINGCLOUD-PROVIDER-WORKREGISTER-8010");
        for (ServiceInstance instancec:instances) {
            System.out.println(
                    instancec.getHost() + "\t" + //主机名称
                    instancec.getPort() + "\t" + //端口号
                    instancec.getUri() + "\t" + //uri
                    instancec.getServiceId() //服务id
            );
        }
        return Result.succ(this.client);
    }

    @PostMapping("/save")
    @Transactional
    public Result save(@RequestBody WorkRegister workRegister) {
        if (workRegister.getTeacherId() == null || workRegister.getTeacherId().equals(""))
            return Result.fail("teacherId不能为空，保存失败");
        if (workRegister.getProjectId() == null || workRegister.getProjectId().equals(""))
            return Result.fail("projectId不能为空，保存失败");
        if (workRegister.getWorkId() == null || workRegister.getWorkId().equals(""))
            return Result.fail("workId不能为空，保存失败");
        workRegister.setCreateTime(DateUtil.date());
        boolean flag = workRegisterService.save(workRegister);
        if (flag) {
            redisUtil.flushByX("workRegister");
            return Result.succ(workRegister);
        }
        return Result.fail("保存失败");
    }

    @PostMapping("/delete")
    @Transactional
    public Result delete(@RequestParam Long id) {
        boolean flag = workRegisterService.removeById(id);
        if (flag) {
            redisUtil.flushByX("workRegister");
            return Result.succ("删除成功");
        }
        return Result.fail("删除失败");
    }

    @PostMapping("/update")
    @Transactional
    public Result update(@RequestBody WorkRegister workRegister) {
        if (workRegister.getTeacherId() == null || workRegister.getTeacherId().equals(""))
            return Result.fail("teacherId不能为空，更新失败");
        if (workRegister.getProjectId() == null || workRegister.getProjectId().equals(""))
            return Result.fail("projectId不能为空，更新失败");
        if (workRegister.getWorkId() == null || workRegister.getWorkId().equals(""))
            return Result.fail("workId不能为空，更新失败");
        workRegister.setCreateTime(DateUtil.date());
        boolean flag = workRegisterService.updateById(workRegister);
        if (flag) {
            redisUtil.flushByX("workRegister");
            return Result.succ(workRegister);
        }
        return Result.fail("修改失败");
    }
}
